2.3 事件详解
添加命令
- 无参数
import tkinter as tk
def callback():
print("被点击了")
root = tk.Tk()
tk.Button(root, text='单击', command=callback).pack()
root.mainloop()
- 有参数
import tkinter as tk
def callback(args):
print("被点击了", args)
root = tk.Tk()
tk.Button(root, text='单击', command=lambda: callback("按钮")).pack()
root.mainloop()
如不想使用lambda
表达式
import tkinter as tk
class Command:
def __init__(self, func, *args):
self.func = func
self.args = args
def __call__(self):
self.func(*self.args)
def callback(args):
print("被点击了", args)
root = tk.Tk()
tk.Button(root, text='单击', command=Command(callback, "按钮")).pack()
root.mainloop()
命令绑定的缺陷:
- 只有
Button
和一小部分控件支持 - 功能单一。命令只能绑定到鼠标左键单击和空格键点击事件,无法实现焦点、鼠标滚轮、快捷键响应等等丰富的交互情况
事件与绑定
所谓事件,就是在用户按下一个键或点击鼠标时,应用程序需要做出的反应。简单说就是对外部刺激做出的反应。
当窗口小控件中注册的事件发生时,会回调关联的处理函数,并将事件对象的实例作为参数传递到这个处理函数中。
鼠标事件
import tkinter as tk
root = tk.Tk()
tk.Label(root, text='单击').pack()
def callback(event):
print("EventType=", event.type)
print("Num=", event.num)
frame = tk.Frame(root, bg='khaki', width=100, height=80)
frame.bind("<Button-1>", callback)
frame.pack()
root.mainloop()
常用的几个鼠标事件
<Button-1>
:鼠标左击事件<Button-2>
:鼠标滚轮点击<Button-3>
:鼠标右击事件<Double-Button-1>
:鼠标左双击事件<Triple-Button-1>
:鼠标左三击事件
关于事件回调传参
之前的命令回调我们都是通过lambda
表达式传参,这里的事件回调也一样,只是稍微有一点区别
# 修改回调函数,添加a、b两个参数
def callback(event, a, b):
print(a, b)
print("EventType=", event.type)
# 注册回调时,在lambda表示中需要定义event参数
frame.bind("<Button-1>", lambda event: callback(event, 1, 2))
键盘事件
import tkinter as tk
root = tk.Tk()
tk.Label(root, text='按键').pack()
def callback(event):
print("EventType=", event.type)
print("keysym=", event.keysym)
frame = tk.Frame(root, bg='khaki', width=100, height=80)
frame.pack()
root.bind("<KeyPress-a>", callback) # a 键
root.bind("<KeyPress-F1>", callback) # F1 键
root.bind("<Control-Alt-a>", callback) # Ctrl + Alt + a 键
root.mainloop()
事件属性(Event类)
char
键盘事件,按键的字符delta
鼠标滚动事件,鼠标滚动的距离height
、width
仅用于Configure事件,即当控件形状发生变化之后的宽度和高度.相当于SizeChanged事件keycode
键盘事件,按键码keysym
、keysym_num
按键事件num
鼠标事件,鼠标按键码,1为左键,2为中建,3为右键serial
相当于Event的IDstate
用来表示修饰键的状态,即ctrl,shift,alt等修饰键的状态.time
事件发生的时间type
事件的类型widget
事件源控件x
、y
,x_root
、y_root
鼠标事件中鼠标的位置。x_root
、·y_root`为绝对坐标,x,y为相对坐标。
绑定级别
事件有三种绑定级别,实际开发中选择合适的一种即可
实例绑定。将事件绑定到一个特定的控件实例上。如上述代码中的鼠标事件绑定到
Frame
实例上frame.bind("<Button-1>", callback)
类级绑定。可以将事件绑定到类的所有窗口小控件上。典型使用如下,所有Entry控件都将绑定到
事件,该事件将调用名为 paste
的函数,类级绑定须慎用,以免造成不可预知的问题!my_entry.bind_class('Entry','<Control-V>',paste)
应用程序级绑定。只要应用程序的任何一个窗口处于焦点,事件发生时回调函数都会被调用。
root.bind_all('<F1>',show_help)
只要应用程序处于焦点,按F1键将始终触发
show_help
函数回调
取消绑定
事件被注册后,是可以取消的,三种级别绑定的取消方法如下
entry.unbind('<Alt-Shift-5>')
root.unbind_all('<F1>')
root.unbind_class('Entry', '<KeyPress-Del>')
手动模拟事件
有时候我们需要用代码模拟生成一个事件,发送给监听者,而不是通过操作事件源产生事件
tkinter中所有的widget
都包含一个公共方法event_generate
,这个方法就是用来产生相应的事件的
event_generate("<<Copy>>")
要想查看这些内置的事件,需要查看Tk/tcl
的文档,tkinter只是对Tk/tcl
的封装,因此tkinter的文档并不是非常全面